<template>
  <div>
    <h3 v-if="title">{{ title }}</h3>
    <div class="tableupside" :style="($slots.status || $slots.edit) ? 'padding:10px 20px' : ''">
      <div class="status" style="max-width: 50%;">
        <slot name="status"></slot>
      </div>
      <div class="edit">
        <slot name="edit"></slot>
      </div>
    </div>
    <el-table :data="tableData" style="width: 100%" :stripe="stripe" :border="border" :row-key="rowkey"
      ref="multipleTableRef" header-row-class-name="tableheader" :span-method="objectSpanMethod"
      :row-style="tableRowClassName" :header-row-style="{ background: '#fefefe30', color: 'var(--color-white)' }"
      :tree-props="{ children: 'children' }" :header-cell-style="{ textAlign: headerAlign }"
      :cell-style="{ padding: '10px 0' }" @selection-change="handleSelectionChange"
      @cell-mouse-enter="(e: any) => emit('cell-mouse-enter', e)"
      @cell-mouse-leave="(e: any) => emit('cell-mouse-leave', e)">
      <el-table-column type="selection" width="55" v-if="selected" />
      <template v-for="item in label" :key="item[0]">
        <el-table-column v-if="!item[1].show || item[1].show(false)" :show-overflow-tooltip="item[1].overflow"
          :label="item[1].label" :width="item[1].width" :sortable="item[1].sortable">
          <template #default="{ row, $index }">
            <component :is="render(row, item, $index)"></component>
          </template>
        </el-table-column>
      </template>
      <slot></slot>
    </el-table>
    <template v-if="hasPagin">
      <el-pagination style="padding:0 10px 10px;" v-model:current-page="current" layout="prev, pager, next, jumper"
        :total="total" :page-size="limit" hide-on-single-page>
      </el-pagination>
      <!-- 分页消失时补位 -->
      <div v-if="total < limit" style="height:36px"></div>
    </template>
    <div class="clearboth"></div>
  </div>
</template>

<script lang="ts" setup>
import { interTable } from "@b/model/base/type";
import { h, isVNode, onMounted, ref, watch, watchEffect } from "vue";

interface prop {
  label: Map<string, interTable>,
  stripe?: boolean
  tableData: any[],
  limit: number
  total: number
  border?: boolean
  isH?: string[]
  title?: string
  hasPagin?: boolean
  headerAlign?: 'start' | 'end' | 'left' | 'right' | 'center' | 'justify' | 'match-parent'
  rowkey?: string
  selected?: any[]
  colors?: string[]
}
const props = withDefaults(defineProps<prop>(),
  { isH: () => [''], limit: 10, border: true, headerAlign: "left", total: 100, rowkey: 'id', hasPagin: true })
const emit = defineEmits(["currentchange", "update:selected", "cell-mouse-enter", "cell-mouse-leave"])
const multipleTableRef = ref()
const current = ref(1);
const spanObj1: any = ref({});
let v: any = null;

watch(() => props.tableData, async () => {
  setTimeout(() => {
    props.selected?.forEach((item: any) => {
      multipleTableRef.value.toggleRowSelection(item)
    })
  }, 1);
})
watch(current, (value: number) => {
  emit("currentchange", value);
});
const tableRowClassName = ({
  rowIndex,
}: {
  rowIndex: number
}) => {
  if (props.colors)
    return { background: props.colors[rowIndex % props.colors.length] }
}
const render = (data: any, item: [string, interTable], index: number) => {
  if (item[1].formatter) {
    v = item[1].formatter(item[0], data, data[item[1].prop], index)
    if (isVNode(v)) {
      return v
    } else {
      return h('span', {}, v)
    }
  } else {
    return h('span', {}, data[item[1].prop] || item[1].default)
  }
}
let spanObj: { [key: string]: number[] } = {};
let pos: { [key: string]: number } = {};
const dataMethod = (data: [], isH?: string | string[] | undefined) => {
  for (let i in data) {
    let dataI = data[i];
    for (let j in dataI as { [key: string]: number[] }) {
      if (parseInt(i) == 0) {
        spanObj[j] = [1];
        pos[j] = 0;
      } else {
        let [e, k] = [dataI, data[parseInt(i) - 1]];
        if (
          k &&
          e[j] == k[j] &&
          (!isH || isH.length == 0 || isH.includes(j))
        ) {
          spanObj[j][pos[j]] += 1;
          spanObj[j].push(0);
        } else {
          spanObj[j] && spanObj[j].push(1);
          pos[j] = parseInt(i);
        }
      }
    }
  }
  return spanObj;
};
watchEffect(() => {
  spanObj1.value = dataMethod(props.tableData as [], props.isH as []);
});
const handleSelectionChange = (val: []) => {
  emit("update:selected", val);
}
const objectSpanMethod = ({
  column,
  rowIndex,
}: {
  column: { property: string };
  rowIndex: number;
}) => {
  let _row = spanObj1[column.property]
    ? spanObj1[column.property][rowIndex]
    : 1;
  let _col = _row > 0 ? 1 : 0;
  return {
    rowspan: _row,
    colspan: _col,
  };
}
</script>
<style scoped>
h3 {
  padding-bottom: 8px;
}

.el-table :deep(.el-table__cell) {
  z-index: auto;
}

.tableupside {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0 20px;
  font-size: 0.9em;
}

.clearboth {
  clear: both;
}
</style>